#define _CRT_SECURE_NO_WARNINGS 1
class Solution {
public:
    int uniquePaths(int m, int n)
    {
        vector<vector<int>> dp(m + 1, vector<int>(n + 1));

        dp[0][1] = 1;
        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= n; j++)
            {
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }

        return dp[m][n];
    }
};

class Solution {
public:


    string longestPalindrome(string s)
    {
        int n = s.size();
        int len = 0;
        int start = 0;
        vector<vector<bool>> dp(n + 1, vector<bool>(n));

        for (int i = n - 1; i >= 0; i--)
            for (int j = i; j < n; j++)
            {
                if (s[i] == s[j])
                {
                    if (i + 1 < j) dp[i][j] = dp[i + 1][j - 1];
                    else dp[i][j] = true;
                }
                if (dp[i][j])
                {
                    if (j - i + 1 > len)
                    {
                        len = j - i + 1;
                        start = i;
                    }
                }
            }


        return s.substr(start, len);
    }
};

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid)
    {
        int m = grid.size();
        int n = grid[0].size();

        vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0x3f3f3f3f));
        dp[0][1] = 0;
        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= n; j++)
            {
                dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
            }

        return dp[m][n];
    }
};

class Solution {
public:
    int longestCommonSubsequence(string text1, string text2)
    {
        int n = text1.size();
        int m = text2.size();

        text1 = ' ' + text1;
        text2 = ' ' + text2;

        vector<vector<int>> dp(n + 1, vector<int>(m + 1));
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
            {
                if (text1[i] == text2[j]) dp[i][j] = dp[i - 1][j - 1] + 1;
                else
                {
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                }

            }


        return dp[n][m];

    }
};

class Solution {
public:
    int minDistance(string word1, string word2)
    {
        int n1 = word1.size();
        int n2 = word2.size();
        word1 = ' ' + word1;
        word2 = ' ' + word2;

        vector<vector<int>> dp(n1 + 1, vector<int>(n2 + 1));


        for (int i = 1; i <= n1; i++) dp[i][0] = dp[i - 1][0] + 1;
        for (int i = 1; i <= n2; i++) dp[0][i] = dp[0][i - 1] + 1;

        for (int i = 1; i <= n1; i++)
            for (int j = 1; j <= n2; j++)
            {
                if (word1[i] == word2[j]) dp[i][j] = dp[i - 1][j - 1];
                else dp[i][j] = dp[i - 1][j - 1] + 1;

                dp[i][j] = min(dp[i][j], min(dp[i - 1][j], dp[i][j - 1]) + 1);
            }

        return dp[n1][n2];
    }
};